﻿using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using System.Text.RegularExpressions;
using Assets.Scripts.UI.Controller;
using UnityEngine;

// Token: 0x020002B8 RID: 696
public class BodyPhysics : MonoBehaviour
{
	// Token: 0x06001002 RID: 4098 RVA: 0x0007593C File Offset: 0x00073B3C
	private void Start()
	{
		this.anim = base.GetComponent<Animator>();
		this.colliders = new List<BodyPhysics.ColliderPair>();
		this.AddDestructionColliders();
		this.model = base.GetComponent<MMD4MecanimModel>();
		if (this.model == null)
		{
			return;
		}
		if (GlobalPreferences.HairPhysics.value)
		{
			this.SetHairPhysics();
		}
		this.torso = BodyPhysics.FindBoneByName(base.gameObject.transform, "torso2");
		if (this.torso == null)
		{
			this.torso = BodyPhysics.FindBoneByName(base.gameObject.transform, "torso");
			if (this.torso == null)
			{
				Debug.LogWarning("No torso object found!");
				return;
			}
		}
		this.PlaceTorsoCollider(this.torso);
		if (GlobalPreferences.BreastPhysics.value)
		{
			this.SetBreastPhysics(this.torso);
		}
	}

	// Token: 0x06001003 RID: 4099 RVA: 0x00075A23 File Offset: 0x00073C23
	public void SetPoseMode(bool poseMode)
	{
		if (this.BreastController != null)
		{
			this.BreastController.enabled = !poseMode;
		}
	}

	// Token: 0x06001004 RID: 4100 RVA: 0x00075A48 File Offset: 0x00073C48
	public void HandleNewBreastPhysics(BreastPhysicsController controller)
	{
		controller.AttachActions(new Action(this.AcceptBreastSettings), new Action(this.CancelBreastSettings), new Action(this.EnableBreastPhysics), new Action(this.DisableBreastPhysics));
		if (this.BreastController != null)
		{
			controller.Dampening = this.BreastController.m_Damping;
			controller.Collider = this.BreastController.m_Colliders.Any<DynamicBoneColliderBase>();
			controller.Elasticity = this.BreastController.m_Elasticity;
			controller.Inert = this.BreastController.m_Inert;
			controller.Stiffness = this.BreastController.m_Stiffness;
		}
		controller.ReloadUi();
		this.mBreastUiPhysicsController = controller;
	}

	// Token: 0x06001005 RID: 4101 RVA: 0x00075B03 File Offset: 0x00073D03
	private void CancelBreastSettings()
	{
		this.mBreastUiPhysicsController = null;
	}

	// Token: 0x06001006 RID: 4102 RVA: 0x00075B0C File Offset: 0x00073D0C
	private void AcceptBreastSettings()
	{
		if (this.BreastController == null)
		{
			return;
		}
		this.BreastController.m_Damping = this.mBreastUiPhysicsController.Dampening;
		this.BreastController.m_Elasticity = this.mBreastUiPhysicsController.Elasticity;
		this.BreastController.m_Inert = this.mBreastUiPhysicsController.Inert;
		this.BreastController.m_Stiffness = this.mBreastUiPhysicsController.Stiffness;
		if (this.BreastController.m_Colliders.Any<DynamicBoneColliderBase>() != this.mBreastUiPhysicsController.Collider)
		{
			if (this.mBreastUiPhysicsController.Collider)
			{
				this.BreastController.m_Colliders = new List<DynamicBoneColliderBase>
				{
					this.mTorsoCollider
				};
			}
			else
			{
				this.BreastController.m_Colliders.Clear();
			}
		}
		this.BreastController.UpdateParameters();
	}

	// Token: 0x06001007 RID: 4103 RVA: 0x00075BF1 File Offset: 0x00073DF1
	public void DisableBreastPhysics()
	{
		if (this.BreastController == null)
		{
			return;
		}
		this.BreastController.enabled = false;
		UnityEngine.Object.Destroy(this.BreastController);
		this.BreastController = null;
	}

	// Token: 0x06001008 RID: 4104 RVA: 0x00075C24 File Offset: 0x00073E24
	public void EnableBreastPhysics()
	{
		if (this.BreastController != null)
		{
			return;
		}
		Transform transform = BodyPhysics.FindBoneByName(base.gameObject.transform, "torso2");
		if (transform == null)
		{
			transform = BodyPhysics.FindBoneByName(base.gameObject.transform, "torso");
			if (transform == null)
			{
				Debug.LogWarning("No torso object found!");
				return;
			}
		}
		this.SetBreastPhysics(transform);
	}

	// Token: 0x06001009 RID: 4105 RVA: 0x00075C99 File Offset: 0x00073E99
	public bool IsBreastSystemEnabled()
	{
		return this.BreastController != null;
	}

	// Token: 0x0600100A RID: 4106 RVA: 0x00075CA7 File Offset: 0x00073EA7
	public void StartBe()
	{
		if (this.mBreastExpansionEnabled)
		{
			return;
		}
		if (this.IsBreastSystemEnabled())
		{
			base.StartCoroutine(this.BreastGrowth());
		}
		else
		{
			Debug.LogError("No Breast Bones found in this model");
		}
	}

	// Token: 0x0600100B RID: 4107 RVA: 0x00075CDC File Offset: 0x00073EDC
	private IEnumerator BreastGrowth()
	{
		this.mBreastExpansionEnabled = true;
		Transform leftBreastTransform = this.Breasts.Aggregate((Transform x, Transform y) => (x.position.y <= y.position.y) ? y : x);
		Transform rigthBreastTransform = this.Breasts.Aggregate((Transform x, Transform y) => (x.position.y >= y.position.y) ? y : x);
		float xOffset = Mathf.Abs(leftBreastTransform.position.y - rigthBreastTransform.position.y) * 10f / base.transform.lossyScale.y;
		this.mBreastExpansionEnabled = true;
		while (this.mBreastExpansionEnabled)
		{
			float scaleModifier = this.BeSpeed * Time.deltaTime;
			leftBreastTransform.localScale *= 1f + scaleModifier;
			leftBreastTransform.localPosition -= Vector3.right * xOffset * scaleModifier;
			leftBreastTransform.localPosition -= Vector3.up * 10f * scaleModifier;
			rigthBreastTransform.localScale *= 1f + scaleModifier;
			rigthBreastTransform.localPosition += Vector3.right * xOffset * scaleModifier;
			rigthBreastTransform.localPosition -= Vector3.up * 10f * scaleModifier;
			yield return null;
		}
		yield break;
	}

	// Token: 0x0600100C RID: 4108 RVA: 0x00075CF8 File Offset: 0x00073EF8
	private void SetHairPhysics()
	{
		Transform boneTransform = this.anim.GetBoneTransform(HumanBodyBones.Head);
		DynamicBone dynamicBone = base.gameObject.AddComponent<DynamicBone>();
		Transform transform = BodyPhysics.FindpreferedHairRoot(boneTransform);
		dynamicBone.m_Root = transform;
		dynamicBone.m_Damping = 0.2f;
		dynamicBone.m_Elasticity = 0.05f;
		dynamicBone.m_Stiffness = 0.7f;
		dynamicBone.m_Inert = 0f;
		dynamicBone.m_Gravity = new Vector3(0f, -1f, 0f);
		dynamicBone.m_EndLength = 1f;
		dynamicBone.m_Radius = 3f;
		dynamicBone.m_DistanceToObject = 100f;
		List<Transform> list = new List<Transform>();
		for (int i = 0; i < transform.childCount; i++)
		{
			Transform child = transform.GetChild(i);
			if (this.IsHairBone(child.name))
			{
				Collider[] componentsInChildren = child.GetComponentsInChildren<Collider>();
				for (int j = 0; j < componentsInChildren.Length; j++)
				{
					list.Add(this.colliders[j].transform);
				}
			}
			else
			{
				list.Add(child);
			}
		}
		dynamicBone.m_Exclusions = list;
		dynamicBone.m_Colliders = new List<DynamicBoneColliderBase>
		{
			this.mTorsoCollider,
			BodyPhysics.PlaceHairHeadCollider(boneTransform)
		};
	}

	// Token: 0x0600100D RID: 4109 RVA: 0x00075E48 File Offset: 0x00074048
	private static Transform FindpreferedHairRoot(Transform head)
	{
		int childCount = head.childCount;
		int num = 0;
		Transform result = null;
		for (int i = 0; i < childCount; i++)
		{
			Transform child = head.GetChild(i);
			if (Regex.IsMatch(child.name, ".*joint.*hair.*", RegexOptions.IgnoreCase))
			{
				num++;
				result = child;
			}
		}
		if (num == 1)
		{
			return result;
		}
		return head;
	}

	// Token: 0x0600100E RID: 4110 RVA: 0x00075EA4 File Offset: 0x000740A4
	private static DynamicBoneColliderBase PlaceHairHeadCollider(Component head)
	{
		DynamicBoneCollider dynamicBoneCollider = head.gameObject.AddComponent<DynamicBoneCollider>();
		dynamicBoneCollider.m_Radius = 100f;
		dynamicBoneCollider.m_Center = new Vector3(0f, 100f, 0f);
		return dynamicBoneCollider;
	}

	// Token: 0x0600100F RID: 4111 RVA: 0x00075EE4 File Offset: 0x000740E4
	private void PlaceTorsoCollider(Component torso)
	{
		DynamicBoneCollider dynamicBoneCollider = torso.gameObject.AddComponent<DynamicBoneCollider>();
		dynamicBoneCollider.m_Radius = 70f;
		dynamicBoneCollider.m_Height = 500f;
		this.mTorsoCollider = dynamicBoneCollider;
	}

	// Token: 0x06001010 RID: 4112 RVA: 0x00075F1C File Offset: 0x0007411C
	private void SetBreastPhysics(Transform torso)
	{
		List<Transform> breasts = new List<Transform>();
		List<Transform> exclusions = new List<Transform>();
		this.FindBreasts(torso.transform, ref breasts, ref exclusions);
		this.CreateBreastJiggleScript(torso.gameObject, torso, exclusions);
		this.Breasts = breasts;
	}

	// Token: 0x06001011 RID: 4113 RVA: 0x00075F5C File Offset: 0x0007415C
	private static Transform FindBoneByName(Transform target, string boneName)
	{
		if (target.name.ToLowerInvariant().Contains(boneName))
		{
			return target;
		}
		int childCount = target.childCount;
		if (childCount == 0)
		{
			return null;
		}
		for (int i = 0; i < childCount; i++)
		{
			Transform child = target.GetChild(i);
			Transform transform = BodyPhysics.FindBoneByName(child, boneName);
			if (transform != null)
			{
				return transform;
			}
		}
		return null;
	}

	// Token: 0x06001012 RID: 4114 RVA: 0x00075FC4 File Offset: 0x000741C4
	private void CreateBreastJiggleScript(GameObject target, Transform torso, List<Transform> exclusions)
	{
		DynamicBone dynamicBone = target.AddComponent<DynamicBone>();
		dynamicBone.m_Root = torso;
		dynamicBone.m_UpdateRate = 60f;
		dynamicBone.m_Damping = 0.2f;
		dynamicBone.m_Elasticity = 0.1f;
		dynamicBone.m_Stiffness = 0.1f;
		dynamicBone.m_Inert = 0.1f;
		dynamicBone.m_Radius = 0f;
		dynamicBone.m_EndLength = 5f;
		dynamicBone.m_EndOffset = new Vector3(-0.1f, -0.1f, 0.3f);
		dynamicBone.m_Gravity = new Vector3(0f, 0f, 0f);
		dynamicBone.m_DistanceToObject = 20f;
		dynamicBone.m_DistantDisable = false;
		dynamicBone.m_Exclusions = exclusions;
		dynamicBone.m_Colliders = new List<DynamicBoneColliderBase>
		{
			this.mTorsoCollider
		};
		this.BreastController = dynamicBone;
		this.BreastController.UpdateParameters();
	}

	// Token: 0x06001013 RID: 4115 RVA: 0x000760A4 File Offset: 0x000742A4
	private void FindBreasts(Transform targetTransform, ref List<Transform> breastBones, ref List<Transform> exlusions)
	{
		string text = targetTransform.name.ToLowerInvariant();
		if (text.Contains("breast") || text.Contains("chichi"))
		{
			breastBones.Add(targetTransform);
		}
		else
		{
			exlusions.Add(targetTransform);
		}
		int childCount = targetTransform.childCount;
		if (childCount == 0)
		{
			return;
		}
		for (int i = 0; i < childCount; i++)
		{
			this.FindBreasts(targetTransform.GetChild(i), ref breastBones, ref exlusions);
		}
	}

	// Token: 0x06001014 RID: 4116 RVA: 0x00076121 File Offset: 0x00074321
	private void FixedUpdate()
	{
		this.UpdateColliderPositions();
	}

	// Token: 0x06001015 RID: 4117 RVA: 0x0007612C File Offset: 0x0007432C
	private void UpdateColliderPositions()
	{
		foreach (BodyPhysics.ColliderPair colliderPair in this.colliders)
		{
			colliderPair.Update();
		}
	}

	// Token: 0x06001016 RID: 4118 RVA: 0x00076188 File Offset: 0x00074388
	private bool IsHairBone(string name)
	{
		string[] array = new string[]
		{
			"Hair",
			"hair",
			"ponite",
			"Palpus",
			"osage",
			"shippo",
			"Burns"
		};
		for (int i = 0; i < array.Length; i++)
		{
			if (name.Contains(array[i]))
			{
				return true;
			}
		}
		return false;
	}

	// Token: 0x06001017 RID: 4119 RVA: 0x000761FC File Offset: 0x000743FC
	public void ColliderEnable(bool enabled)
	{
		if (this.colliders == null)
		{
			return;
		}
		foreach (BodyPhysics.ColliderPair colliderPair in this.colliders)
		{
			colliderPair.collider.enabled = enabled;
		}
	}

	// Token: 0x06001018 RID: 4120 RVA: 0x0007626C File Offset: 0x0007446C
	public void Destroy()
	{
		if (!this.collidersParent)
		{
			return;
		}
		EntityBase[] componentsInChildren = this.collidersParent.GetComponentsInChildren<EntityBase>();
		for (int i = 0; i < componentsInChildren.Length; i++)
		{
			componentsInChildren[i].transform.SetParent(null);
		}
		for (int j = 0; j < componentsInChildren.Length; j++)
		{
			componentsInChildren[j].DestroyObject(false);
		}
		UnityEngine.Object.Destroy(this.collidersParent.gameObject);
	}

	// Token: 0x06001019 RID: 4121 RVA: 0x000762E8 File Offset: 0x000744E8
	private void AddDestructionColliders()
	{
		this.AddSimpleCollider(this.anim.GetBoneTransform(HumanBodyBones.LeftFoot));
		this.AddSimpleCollider(this.anim.GetBoneTransform(HumanBodyBones.RightFoot));
		this.AddSimpleCollider(this.anim.GetBoneTransform(HumanBodyBones.Spine));
		this.AddSimpleCollider(this.anim.GetBoneTransform(HumanBodyBones.Head));
		this.AddSimpleCollider(this.anim.GetBoneTransform(HumanBodyBones.Hips));
		this.AddSimpleCollider(this.anim.GetBoneTransform(HumanBodyBones.LeftLowerArm));
		this.AddSimpleCollider(this.anim.GetBoneTransform(HumanBodyBones.RightLowerArm));
		this.AddSimpleCollider(this.anim.GetBoneTransform(HumanBodyBones.LeftLowerLeg));
		this.AddSimpleCollider(this.anim.GetBoneTransform(HumanBodyBones.RightLowerLeg));
		this.AddSimpleCollider(this.anim.GetBoneTransform(HumanBodyBones.LeftHand));
		this.AddSimpleCollider(this.anim.GetBoneTransform(HumanBodyBones.RightHand));
	}

	// Token: 0x0600101A RID: 4122 RVA: 0x000763C0 File Offset: 0x000745C0
	private void AddSimpleCollider(Transform bone)
	{
		SphereCollider sphereCollider = new GameObject(bone.name + " collider").AddComponent<SphereCollider>();
		sphereCollider.transform.SetParent(base.transform);
		sphereCollider.transform.localScale = Vector3.one;
		sphereCollider.radius = 50f;
		sphereCollider.gameObject.AddComponent<Rigidbody>();
		sphereCollider.gameObject.AddComponent<Destructor>().baseSize = 1000f;
		sphereCollider.gameObject.layer = Layers.destroyerLayer;
		this.colliders.Add(new BodyPhysics.ColliderPair(bone, sphereCollider));
	}

	// Token: 0x040014E1 RID: 5345
	public bool ignore;

	// Token: 0x040014E2 RID: 5346
	public float BeSpeed;

	// Token: 0x040014E3 RID: 5347
	private bool mBreastExpansionEnabled;

	// Token: 0x040014E4 RID: 5348
	private DynamicBoneColliderBase mTorsoCollider;

	// Token: 0x040014E5 RID: 5349
	private DynamicBone BreastController;

	// Token: 0x040014E6 RID: 5350
	private List<Transform> Breasts;

	// Token: 0x040014E7 RID: 5351
	private BreastPhysicsController mBreastUiPhysicsController;

	// Token: 0x040014E8 RID: 5352
	private Transform torso;

	// Token: 0x040014E9 RID: 5353
	private Transform collidersParent;

	// Token: 0x040014EA RID: 5354
	private MMD4MecanimModel model;

	// Token: 0x040014EB RID: 5355
	private Animator anim;

	// Token: 0x040014EC RID: 5356
	private List<BodyPhysics.ColliderPair> colliders;

	// Token: 0x020002B9 RID: 697
	public class ColliderPair
	{
		// Token: 0x0600101B RID: 4123 RVA: 0x00076457 File Offset: 0x00074657
		public ColliderPair(Transform transform, Collider collider)
		{
			this.transform = transform;
			this.collider = collider;
			this.rigidbody = collider.gameObject.GetComponent<Rigidbody>();
			this.rigidbody.useGravity = false;
		}

		// Token: 0x0600101C RID: 4124 RVA: 0x0007648A File Offset: 0x0007468A
		public void Update()
		{
			this.rigidbody.MovePosition(this.transform.position);
		}

		// Token: 0x040014ED RID: 5357
		public Transform transform;

		// Token: 0x040014EE RID: 5358
		public Collider collider;

		// Token: 0x040014EF RID: 5359
		public Rigidbody rigidbody;
	}
}
